Skip to content

Conversation

@dmaluka
Copy link
Collaborator

@dmaluka dmaluka commented May 25, 2025

Fixes #3455

Micro "allows" plugins to register colorschemes via config.AddRuntimeFile(). However, that has never really worked, since InitColorscheme() is called earlier than plugins init() or even preinit() callbacks are called.

To work around that, colorscheme plugins (e.g. https://github.com/KiranWells/micro-nord-tc-colors) are using a tricky hack: call config.AddRuntimeFile() not in init() or preinit() but directly in Lua's global scope, so that it is called even earlier, when the plugin's Lua code is loaded. This hack is not guaranteed to work, and works by chance. Furthermore, it only works when starting micro, and doesn't work after the reload command. (The reason it doesn't work is that PluginAddRuntimeFile() calls FindPlugin() which calls IsLoaded() which returns false, since, well, the plugin is not loaded, it is only being loaded. And the reason why it works when starting micro is that in that case IsLoaded() confusingly returns true, since GlobalSettings[p.Name] has not been set yet.)

Moreover, after PR #3343 even this hack stopped working, since we added validation of option values (including the colorscheme option) when reading them from settings.json, which happens even earlier than loading plugins. So validation checks if the colorscheme exists, and it doesn't exist yet, since it has not been registered by the plugin yet.

So, this PR does 2 things:

  1. Fix the regression caused by #3343 by disabling early validation for the colorscheme option only (treating this option as a special case). We "validate" it later: when we try to load this colorscheme and fail, we reset it to the default colorscheme.

This fix is quite ad-doc and a bit hacky, so any better suggestions are welcome.

  1. Fix the original issue: postpone loading colorschemes after fully initializing plugins (i.e. after executing init(), preinit() and postinit() callbacks), so that plugins can finally successfully register colorschemes in those callbacks, instead of using the above tricky hack which is not guaranteed to work.

@dmaluka dmaluka mentioned this pull request May 25, 2025
@dmaluka
Copy link
Collaborator Author

dmaluka commented May 25, 2025

[...] And the reason why it works when starting micro is that in that case IsLoaded() confusingly returns true, since GlobalSettings[p.Name] has not been set yet.

BTW @JoeKar you might have some thoughts about this, since this is directly related to your #2836 (although it didn't change the behavior of IsLoaded(), but it changed its name, creating this confusion.)

@Neko-Box-Coder
Copy link
Contributor

Neko-Box-Coder commented May 25, 2025

I am not into the details but just to chime in since I maintain quite a few plugins myself.

Regarding

Micro "allows" plugins to register colorschemes via config.AddRuntimeFile(). However, that has never really worked, since InitColorscheme() is called earlier than plugins init() or even preinit() callbacks are called.

Are you implying that config.AddRuntimeFile() doesn't work in init()?

If so, I don't think that is the case, I am on master.

config.AddRuntimeFile() works just fine in the function init() for me. At least for my filemanager2 and a few other plugins.

Can't comment on plugins that call config.AddRuntimeFile() globally tho.

Sorry, forget what I said. I totally misread the whole thing as syntax file instead.

@JoeKar
Copy link
Collaborator

JoeKar commented May 26, 2025

although it didn't change the behavior of IsLoaded(), but it changed its name, creating this confusion.

// IsLoaded returns if a plugin is enabled
func (p *Plugin) IsLoaded() bool {
if v, ok := GlobalSettings[p.Name]; ok {
return v.(bool) && p.Loaded
}
return true
}

Indeed, I missed that as well as updating the documentation.
The rename was necessary, at least from my perspective, to differentiate between the global plugin state and the per-buffer state.
It was not my intention to cause confusion.

Should we fix this here too? I assume it will finally break https://github.com/KiranWells/micro-nord-tc-colors till it is adapted accordingly (move config.AddRuntimeFile() into init() or preinit()).

Copy link
Collaborator

@JoeKar JoeKar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A feasible workaround so far.
Maybe we find something better in the future.

What about IsLoaded()...do we change it with this PR?

@dmaluka
Copy link
Collaborator Author

dmaluka commented May 31, 2025

What about IsLoaded()...do we change it with this PR?

I haven't thought what to do with it. Anyway, we don't need to do anything with it in this PR.

dmaluka added 2 commits June 24, 2025 22:24
Adding early validation of options in ReadSettings() caused a regression:
colorschemes registered by plugins via config.AddRuntimeFile() stopped
working, since ReadSettings() is called when plugins are not initialized
(or even loaded) yet, so a colorscheme is not registered yet and thus
its validation fails.

Fix that with an ad-hoc fix: treat the "colorscheme" option as a special
case and do not verify it early when reading settings.json, postponing
that until the moment when we try to load this colorscheme.
Micro "allows" plugins to register colorschemes via
config.AddRuntimeFile(). However, that has never really worked, since
InitColorscheme() is called earlier than plugins init() or even
preinit() callbacks are called.

To work around that, plugins that use it (e.g. nord-tc [1]) are using a
tricky hack: call config.AddRuntimeFile() not in init() or preinit() but
directly in Lua's global scope, so that it is called earlier, when the
plugin's Lua code is loaded. This hack is not guaranteed to work, and
works by chance. Furthermore, it only works when starting micro, and
doesn't work after the `reload` command. (The reason it doesn't work is
that PluginAddRuntimeFile() calls FindPlugin() which calls IsLoaded()
which returns false, since, well, the plugin is not loaded, it is only
being loaded. And the reason why it works when starting micro is that
in that case IsLoaded() confusingly returns true, since
GlobalSettings[p.Name] has not been set yet.)

So move InitColorscheme() call after calling plugins init/preinit/
postinit callbacks, to let plugins successfully register colorschemes
in any of those callbacks instead of using the aforementioned hack.

[1] https://github.com/KiranWells/micro-nord-tc-colors
@dmaluka dmaluka force-pushed the colorscheme-plugins-regression-fix branch from fe714b1 to e923640 Compare June 24, 2025 20:31
@JoeKar JoeKar merged commit da02f83 into zyedidia:master Jun 25, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Color scheme issue

3 participants